/*
The MIT License
Copyright (c) 2019 Lehrstuhl Informatik 11 - RWTH Aachen University
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE

This file is part of embeddedRTPS.

Author: i11 - Embedded Software, RWTH Aachen University
*/

#ifndef RTPS_PARTICIPANTPROXYDATA_H
#define RTPS_PARTICIPANTPROXYDATA_H

#include <time.h>
#include "rtps/common/Locator.h"
#include "rtps/config.h"
#include "rtps/messages/MessageTypes.h"
#include "ucdr/microcdr.h"
//#if defined(unix) || defined(__unix__)
//#include <chrono>
//#endif
//#include <array>
typedef uint32_t BuiltinEndpointSet_t;

typedef struct rtps_ParticipantProxyData {
    ProtocolVersion_t m_protocolVersion;
    Guid_t m_guid;
    VendorId_t m_vendorId;
    bool m_expectsInlineQos;
    BuiltinEndpointSet_t m_availableBuiltInEndpoints;
    Locator m_metatrafficUnicastLocatorList[SPDP_MAX_NUM_LOCATORS];
    Locator m_metatrafficMulticastLocatorList[SPDP_MAX_NUM_LOCATORS];
    Locator m_defaultUnicastLocatorList[SPDP_MAX_NUM_LOCATORS];
    Locator m_defaultMulticastLocatorList[SPDP_MAX_NUM_LOCATORS];
    Count_t m_manualLivelinessCount;
    Duration_t m_leaseDuration;
#if defined(unix) || defined(__unix__)
    struct timeval m_lastLivelinessReceivedTimestamp;
#else
    TickType_t m_lastLivelinessReceivedTickCount;
#endif
}ParticipantProxyData;

static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER = 1 << 0;
static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR =
    1 << 1;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER = 1 << 2;
static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR =
    1 << 3;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER = 1 << 4;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR = 1 << 5;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_ANNOUNCER = 1 << 6;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_DETECTOR = 1 << 7;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_ANNOUNCER = 1 << 8;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_DETECTOR = 1 << 9;
static const BuiltinEndpointSet_t
    BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER = 1 << 10;
static const BuiltinEndpointSet_t
    BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER = 1 << 11;

#if 0
ProtocolVersion_t m_protocolVersion = PROTOCOLVERSION;
Guid_t m_guid = {GUIDPREFIX_UNKNOWN, ENTITYID_UNKNOWN};
VendorId_t m_vendorId = VENDOR_UNKNOWN;
bool m_expectsInlineQos = false;
BuiltinEndpointSet_t m_availableBuiltInEndpoints;
//std::array<Locator, Config::SPDP_MAX_NUM_LOCATORS>
Locator m_metatrafficUnicastLocatorList[SPDP_MAX_NUM_LOCATORS];
//std::array<Locator, Config::SPDP_MAX_NUM_LOCATORS>
Locator m_metatrafficMulticastLocatorList[SPDP_MAX_NUM_LOCATORS];
//std::array<Locator, Config::SPDP_MAX_NUM_LOCATORS>
Locator m_defaultUnicastLocatorList[SPDP_MAX_NUM_LOCATORS];
//std::array<Locator, Config::SPDP_MAX_NUM_LOCATORS>
Locator m_defaultMulticastLocatorList[SPDP_MAX_NUM_LOCATORS];
/* ???? *///Count_t m_manualLivelinessCount{1};
Count_t m_manualLivelinessCount = {1};
Duration_t m_leaseDuration = SPDP_DEFAULT_REMOTE_LEASE_DURATION;
#if defined(unix) || defined(__unix__)
/* ???? */
/* second */
//std::chrono::time_point<std::chrono::high_resolution_clock>
//    m_lastLivelinessReceivedTimestamp;
struct timeval m_lastLivelinessReceivedTimestamp;
#else
TickType_t m_lastLivelinessReceivedTickCount = 0;
#endif

static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER = 1 << 0;
static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR =
    1 << 1;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER = 1 << 2;
static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR =
    1 << 3;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER = 1 << 4;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR = 1 << 5;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_ANNOUNCER = 1 << 6;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_DETECTOR = 1 << 7;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_ANNOUNCER = 1 << 8;
static const BuiltinEndpointSet_t
    DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_DETECTOR = 1 << 9;
static const BuiltinEndpointSet_t
    BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER = 1 << 10;
static const BuiltinEndpointSet_t
    BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER = 1 << 11;
#endif

#if 0
extern ProtocolVersion_t m_protocolVersion;
extern Guid_t m_guid;
extern VendorId_t m_vendorId;
extern bool m_expectsInlineQos;
extern BuiltinEndpointSet_t m_availableBuiltInEndpoints;
extern Locator m_metatrafficUnicastLocatorList[SPDP_MAX_NUM_LOCATORS];
extern Locator m_metatrafficMulticastLocatorList[SPDP_MAX_NUM_LOCATORS];
extern Locator m_defaultUnicastLocatorList[SPDP_MAX_NUM_LOCATORS];
extern Locator m_defaultMulticastLocatorList[SPDP_MAX_NUM_LOCATORS];
extern Count_t m_manualLivelinessCount;
extern Duration_t m_leaseDuration;
#if defined(unix) || defined(__unix__)
extern struct timeval m_lastLivelinessReceivedTimestamp;
#else
extern TickType_t m_lastLivelinessReceivedTickCount;
#endif

extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PUBLICATION_ANNOUNCER;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PUBLICATION_DETECTOR;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_DETECTOR;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_ANNOUNCER;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_PROXY_DETECTOR;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_ANNOUNCER;
extern static const BuiltinEndpointSet_t DISC_BUILTIN_ENDPOINT_PARTICIPANT_STATE_DETECTOR;
extern static const BuiltinEndpointSet_t BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER;
extern static const BuiltinEndpointSet_t BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER;
#endif

ParticipantProxyData *rtps_ParticipantProxyData_Init_Default(ParticipantProxyData *pin);
ParticipantProxyData *rtps_ParticipantProxyData_Init(ParticipantProxyData *pin, Guid_t guid);

void rtps_ParticipantProxyData_reset();

bool rtps_ParticipantProxyData_readFromUcdrBuffer(ParticipantProxyData *pin, ucdrBuffer *buffer);

bool rtps_ParticipantProxyData_hasParticipantWriter(ParticipantProxyData *pin);
bool rtps_ParticipantProxyData_hasParticipantReader(ParticipantProxyData *pin);
bool rtps_ParticipantProxyData_hasPublicationWriter(ParticipantProxyData *pin);
bool rtps_ParticipantProxyData_hasPublicationReader(ParticipantProxyData *pin);
bool rtps_ParticipantProxyData_hasSubscriptionWriter(ParticipantProxyData *pin);
bool rtps_ParticipantProxyData_hasSubscriptionReader(ParticipantProxyData *pin);

void rtps_ParticipantProxyData_onAliveSignal(ParticipantProxyData *pin);
bool rtps_ParticipantProxyData_isAlive(ParticipantProxyData *pin);
uint32_t rtps_ParticipantProxyData_getAliveSignalAgeInMilliseconds(ParticipantProxyData *pin);

bool rtps_ParticipantProxyData_readLocatorIntoList(ucdrBuffer *buffer,
                                                     Locator *list);

#endif // RTPS_PARTICIPANTPROXYDATA_H
